package cn.edu.csust.coursecard.service.impl;

import cn.edu.csust.coursecard.common.CodeEnum;
import cn.edu.csust.coursecard.common.ReturnData;
import cn.edu.csust.coursecard.dao.dto.*;
import cn.edu.csust.coursecard.exception.BaseException;
import cn.edu.csust.coursecard.service.IParseHtmlService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ParseHtmlServiceImpl implements IParseHtmlService {
    
    
    @Override
    public Course[][] parseWeekCourseHtml(String weekCourseHtml) {
        try{
            Document document = Jsoup.parse(weekCourseHtml);
            Elements trs = document.select("tbody").select("tr");
    
            Course[][] courses = new Course[5][7];
            for (int i = 0; i < 5; i++) {
                Elements tds = trs.get(i).select("td");
                for (int j = 1; j < 8; j++) {
                    Elements p = tds.get(j).select("p");
                    String title = p.attr("title");
                    if (!"".equals(title.trim())) {
                        String[] properties = title.split("<br/>");
                        Course course = new Course();
                        for (int k = 0; k < 5; k++) {
                            String[] split = properties[k].split("：");
                            switch (k) {
                                case 0:
                                    if (split.length == 2) {
                                        course.setXuefen(split[1]);
                                    } else {
                                        course.setXuefen(null);
                                    }
                                    break;
                                case 1:
                                    if (split.length == 2) {
                                        course.setProperty(split[1]);
                                    } else {
                                        course.setProperty(null);
                                    }
                                    break;
                                case 2:
                                    if (split.length == 2) {
                                        course.setCouseName(split[1]);
                                    } else {
                                        course.setCouseName(null);
                                    }
                                    break;
                                case 3:
                                    if (split.length == 2) {
                                        course.setTime(split[1]);
                                    } else {
                                        course.setTime(null);
                                    }
                                    break;
                                case 4:
                                    if (split.length == 2) {
                                        course.setAddress(split[1]);
                                    } else {
                                        course.setAddress(null);
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                        courses[i][j - 1] = course;
                    }
                }
            }
            return courses;
        }catch (Exception e){
            throw new BaseException(CodeEnum.PARSE_ERROR,"解析周课表失败");
        }
        
    }
    
    @Override
    public WeekCourse[][] parseCourseHtml(String courseHtml) {
        try{
            Document document = Jsoup.parse(courseHtml);
            Elements trs = document.select("table").select("tr");
            WeekCourse[][] weekCourses = new WeekCourse[5][7];
            if (trs.size() <= 2) {
                throw new BaseException(CodeEnum.REQUEST_FAILED.getCode(), "教务系统暂无该课表");
            }
            for (int i = 1; i < 6; i++) {
                Elements kbcontent = trs.get(i).getElementsByClass("kbcontent");
        
                for (int j = 0; j < 7; j++) {
                    Elements elements = kbcontent.get(j).select("font");
                    String courseName = kbcontent.get(j).ownText();
                    if (j == 0) {
                        if (!"".equals(courseName)) {
                            WeekCourse weekCourse = new WeekCourse();
                            weekCourse.setCourseName(courseName);
                            weekCourse.setTeacher(elements.select("[title=老师]").text().split("（")[0]);
                            weekCourse.setAddress(elements.select("[title=教室]").text());
                            weekCourse.setTime(elements.select("[title=周次(节次)]").text());
                            weekCourses[i - 1][6] = weekCourse;
                        }
                        continue;
                    }
            
                    if (!courseName.isEmpty()) {
                        WeekCourse weekCourse = new WeekCourse();
                        weekCourse.setCourseName(courseName);
                        weekCourse.setTeacher(elements.select("[title=老师]").text());
                        weekCourse.setAddress(elements.select("[title=教室]").text());
                        weekCourse.setTime(elements.select("[title=周次(节次)]").text());
                        weekCourses[i - 1][j - 1] = weekCourse;
                    }
                }
            }
            return weekCourses;
        }catch (Exception e){
            if(e instanceof BaseException){
                throw e;
            }else {
                throw new BaseException(CodeEnum.PARSE_ERROR,"解析课表失败");
            }
        }
    }
    
    @Override
    public List<Exam> parseExamArrangementHtml(String examHtml) {
        try{
            List<Exam> examList = new LinkedList<>();
            Document document = Jsoup.parse(examHtml);
            Element dataList = document.getElementById("dataList");
            if(dataList == null){
                throw new BaseException(CodeEnum.PARSE_ERROR);
            }
            //这一行空指针了
            Elements trs = dataList.select("tr");
            /*if (trs.size() < 2) {
                return ReturnData.fail(CodeEnum.REQUEST_FAILED.getCode(), "教务系统暂无该学期的考试安排");
            }*/
            if (trs.size() < 2 || "未查询到数据".equals(trs.get(1).text())) {
                throw new BaseException(CodeEnum.REQUEST_FAILED.getCode(), "教务系统暂无该学期的考试安排");
            }
            for (int i = 1; i < trs.size(); i++) {
                Element element = trs.get(i);
                Elements tds = element.select("td");
                Exam exam = new Exam();
                for (int j = 0; j < tds.size(); j++) {
                    switch (j) {
                        case 1:
                            exam.setCampus(tds.get(j).text());
                            break;
                        case 4:
                            exam.setCourseName(tds.get(j).text());
                            break;
                        case 5:
                            exam.setTeacher(tds.get(j).text());
                            break;
                        case 6:
                            String time = tds.get(j).text();
                            if (!"".equals(time.trim())) {
                                String[] strings = time.split(" ");
                                String[] times = strings[1].split("~");
                                exam.setStartTime(strings[0] + " " + times[0]);
                                exam.setEndTime(strings[0] + " " + times[1]);
                            }
                            break;
                        case 7:
                            exam.setAddress(tds.get(j).text());
                            break;
                        case 8:
                            exam.setSeatNumber(tds.get(j).text());
                            break;
                        case 9:
                            exam.setTicketNumber(tds.get(j).text());
                            break;
                        default:
                            break;
                    }
                }
                examList.add(exam);
            }
            return examList;
        }catch (Exception e){
            if(e instanceof BaseException){
                throw e;
            }else {
                throw new BaseException(CodeEnum.PARSE_ERROR,"解析考试安排失败");
            }
        }
    }
    
    @Override
    public List<Score> parseScoreHtml(String scoreHtml) {
        try{
            List<Score> scoreList = new LinkedList<>();
            Document document = Jsoup.parse(scoreHtml);
            Element dataList = document.getElementById("dataList");
            if(dataList == null){
                throw new BaseException(CodeEnum.PARSE_ERROR);
            }
            Elements trs = dataList.select("tr");
            if (trs.size() < 2 || scoreHtml.contains("评教未完成，不能查询成绩！")) {
                throw new BaseException(CodeEnum.REQUEST_FAILED.getCode(), "评教未完成，请先完成评教");
            }
            if ("未查询到数据".equals(trs.get(1).child(0).ownText())) {
                throw new BaseException(CodeEnum.REQUEST_FAILED.getCode(), "暂无该学期成绩");
            }
            for (int i = 1; i < trs.size(); i++) {
                Elements tds = trs.get(i).select("td");
                Score score = new Score();
                for (int j = 1; j < tds.size(); j++) {
                    switch (j) {
                        case 1:
                            score.setXueqi(tds.get(j).ownText());
                            break;
                        case 3:
                            score.setCourseName(tds.get(j).ownText());
                            break;
                        case 5:
                            score.setScore(tds.get(j).text());
                            Elements a = tds.get(j).select("a");
                            String href = a.attr("href");
                            if (!"".equals(href)) {
                                String[] split = href.split("'");
                                score.setPscjUrl(split[1]);
                            }
                            break;
                        case 7:
                            score.setType(tds.get(j).ownText());
                            break;
                        case 8:
                            score.setXuefen(tds.get(j).ownText());
                            break;
                        case 10:
                            score.setPoint(tds.get(j).ownText());
                            break;
                        case 12:
                            score.setMethod(tds.get(j).ownText());
                            break;
                        case 14:
                            score.setProperty(tds.get(j).ownText());
                            break;
                        case 15:
                            score.setNature(tds.get(j).ownText());
                            break;
                        default:
                            break;
                    }
                }
                scoreList.add(score);
            }
            return scoreList;
        }catch (Exception e){
            if(e instanceof BaseException){
                throw e;
            }else {
                throw new BaseException(CodeEnum.PARSE_ERROR);
            }
        }
    }
    
    @Override
    public PscjInfo parseScoreDetailHtml(String scoreDetailHtml) {
        try {
            HashMap<String, Integer> map = new HashMap<>();
            Document document = Jsoup.parse(scoreDetailHtml);
            Elements elements = document.select("#dataList");
            Elements trs = elements.select("tr");
            Element nameTr = trs.get(0);
            Elements ths = nameTr.select("th");
            int index = 0;
            for (Element th : ths) {
                String name = th.ownText();
                switch (name) {
                    case "平时成绩":
                        map.put("pscj", index);
                        break;
                    case "平时成绩比例":
                        map.put("pscjBL", index);
                
                        break;
                    case "期末成绩":
                        map.put("qmcj", index);
                
                        break;
                    case "期末成绩比例":
                        map.put("qmcjBL", index);
                
                        break;
                    case "总成绩":
                        map.put("totalScore", index);
                        break;
                    case "期中成绩":
                        map.put("qzcj", index);
                        break;
                    case "期中成绩比例":
                        map.put("qzcjBL", index);
                        break;
                }
                index++;
            }
    
            Element pscjTr = trs.get(1);
            Elements tds = pscjTr.select("td");
            PscjInfo pscjInfo = new PscjInfo();
    
            for (Map.Entry<String, Integer> entry : map.entrySet()) {
                String key = entry.getKey();
                Integer value = entry.getValue();
                if ("pscj".equals(key)) {
                    pscjInfo.setPscj(tds.get(value).ownText());
                } else if ("pscjBL".equals(key)) {
                    pscjInfo.setPscjBL(tds.get(value).ownText());
                } else if ("qmcj".equals(key)) {
                    pscjInfo.setQmcj(tds.get(value).ownText());
                } else if ("qmcjBL".equals(key)) {
                    pscjInfo.setQmcjBL(tds.get(value).ownText());
                } else if ("totalScore".equals(key)) {
                    pscjInfo.setScore(tds.get(value).ownText());
                } else if ("qzcj".equals(key)) {
                    pscjInfo.setQzcj(tds.get(value).ownText());
                } else if ("qzcjBL".equals(key)) {
                    pscjInfo.setQzcjBL(tds.get(value).ownText());
                }
            }
//			pscjInfo.setKscj(tds.get(7).ownText());
//			pscjInfo.setKscjBL(tds.get(8).ownText());
//			pscjInfo.setPscj(tds.get(3).ownText());
//			pscjInfo.setPscjBL(tds.get(4).ownText());
//			pscjInfo.setScore(tds.get(9).ownText());
            return pscjInfo;
        }catch (Exception e){
            throw new BaseException(CodeEnum.PARSE_ERROR,"解析平时成绩失败");
        }
        
    }
    
    @Override
    public List<JWNotice> parseNoticeHtml(String noticeHtml) {
        try {
            List<JWNotice> jwNoticeList = new ArrayList<>();
            Document document = Jsoup.parse(noticeHtml);
            Element body = document.body();
            Elements trs = body.select("tr");
            int index = 0;
    
            for (Element tr : trs) {
                if (index >= 1) {
                    Elements tds = tr.select("td");
                    int index1 = 1;
                    JWNotice jwNotice = new JWNotice();
                    for (Element td : tds) {
                        switch (index1) {
                            case 1:
                                jwNotice.setIndex(td.text());
                                break;
                            case 2:
                                jwNotice.setTitle(td.text());
                                break;
                            case 3:
                                jwNotice.setCategory(td.text());
                                break;
                            case 4:
                                jwNotice.setSender(td.text());
                                break;
                            case 5:
                                jwNotice.setTime(td.text());
                                break;
                            case 6:
                                String href = td.select("a").attr("href");
                                String[] strings = href.split("=");
                                String ggid = strings[1].substring(0, 32);
                                jwNotice.setGgid(ggid);
                                break;
                            default:
                                break;
                        }
                        index1++;
                    }
                    jwNoticeList.add(jwNotice);
                }
                index++;
            }
            return jwNoticeList;
        }catch (Exception e){
            throw new BaseException(CodeEnum.PARSE_ERROR,"解析教务通知失败");
        }
        
    }
    
    public List<Integer> parseWeekDateHtml(String weekDateHtml){
        try {
            List<Integer> nowWeekDate = new ArrayList<>();
            Document document = Jsoup.parse(weekDateHtml);
            Element body = document.body();
            Element liShowWeekDiv = body.getElementById("li_showWeek");
            Elements nowWeekDiv = body.getElementsByClass("main_text main_color");
    
            int nowWeek;
            try {
                nowWeek = Integer.parseInt(nowWeekDiv.text().substring(1, nowWeekDiv.text().length() - 1));
            } catch (Exception e) {
                throw new BaseException(CodeEnum.SYSTEM_ERROR.getCode(), "教务系统无响应！");
                //nowWeek = -1;
            }
            int totalWeek;
            try {
                String totalWeekStr = liShowWeekDiv.text().split("/")[1];
                totalWeek = Integer.parseInt(totalWeekStr.substring(0, totalWeekStr.length() - 1));
            } catch (Exception e) {
                totalWeek = 20;
            }
    
            nowWeekDate.add(nowWeek);
            nowWeekDate.add(totalWeek);
    
            return nowWeekDate;
        }catch (Exception e){
            throw new BaseException(CodeEnum.PARSE_ERROR,"解析周时间失败");
        }
        
    }
    
    
}
